/*
 * 面板基本单位panel
 */

#include "gui.h"
#include <stdlib.h>
#include <string.h>

void ACALLBACK __panel_mouse_down(struct Area *who,
				   int button, int x, int y, 
				   void *userdata)
{
	struct Panel *pn = (struct Panel *) userdata;
	if (pn -> mouse_down)
		(*pn -> mouse_down)(pn, button, x, y, pn -> userdata);
}

void ACALLBACK __panel_mouse_up(struct Area *who,
				 int button, int x, int y, 
				 void *userdata)
{
	struct Panel *pn = (struct Panel *) userdata;
	if (pn -> mouse_up)
		(*pn -> mouse_up)(pn, button, x, y, pn -> userdata);
}

void ACALLBACK __panel_mouse_move(struct Area *who,
				int x, int y, 
				void *userdata)
{
	struct Panel *pn = (struct Panel *) userdata;
	if (pn -> mouse_move)
		(*pn -> mouse_move)(pn, x, y, pn -> userdata);
}

void ACALLBACK __panel_render(struct Area *who, void *userdata)
{
	struct Panel *pn = (struct Panel *) userdata;
	
	//video_bar(who -> _x, who -> _y,
	//	  who -> _x + who -> _width, who -> _y + who -> _height);
	//video_set_color(0, 0, 0);
	//video_rectangle(who -> _x, who -> _y,
	//		who -> _x + who -> _width, who -> _y + who -> _height);
	if (pn -> user_render)
		(*pn -> user_render)(pn, pn -> userdata);
}

void ACALLBACK __panel_mouse_enter(struct Area *who, void *userdata)
{
	struct Panel *pn = (struct Panel *) userdata;
	if (pn -> enter)
		(*pn -> enter)(pn, pn -> userdata);
}

void ACALLBACK __panel_mouse_leave(struct Area *who, void *userdata)
{
	struct Panel *pn = (struct Panel *) userdata;
	if (pn -> leave)
		(*pn -> leave)(pn, pn -> userdata);
}

struct Panel *panel_new(struct Panel *father, int x, int y,
			  int width, int height)
{
	struct Panel *ret;
	ret = malloc(sizeof(struct Panel));
	memset(ret, 0, sizeof(struct Panel));
	
	ret -> px = x;
	ret -> py = y;
	
	struct Area *a;
	int xx, yy;
	if (father) {		//转换成绝对坐标
		a = father -> _area;
		xx = father -> _area -> _x + x;
		yy = father -> _area -> _y + y;
	} else {
		a = NULL;
		xx = x;
		yy = y;
	}
	ret -> _area = area_new(a, xx, yy, width, height);
	
	ret -> _area -> enable = 1;
	ret -> _area -> visual = 1;
	ret -> _area -> userdata = ret;
	
	ret -> _area -> mouse_down = __panel_mouse_down;
	ret -> _area -> mouse_up = __panel_mouse_up;
	ret -> _area -> mouse_move = __panel_mouse_move;
	ret -> _area -> mouse_enter = __panel_mouse_enter;
	ret -> _area -> mouse_leave = __panel_mouse_leave;
	
	ret -> _area -> user_render = __panel_render;
	return ret;
}


void panel_delete(struct Panel *father, struct Panel *pn)
{
	area_delete((father ? father -> _area : NULL),
		     pn -> _area);
	free(pn);
}

void panel_mouse_down(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, int button, int x, int y, void *userdata))
{
	pn -> mouse_down = f;
}

void panel_mouse_up(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, int button, int x, int y, void *userdata))
{
	pn -> mouse_up = f;
}

void panel_mouse_move(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, int x, int y, void *userdata))
{
	pn -> mouse_move = f;
}

void panel_user_render(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, void *userdata))
{
	pn -> user_render = f;
}

void panel_mouse_enter(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, void *userdata))
{
	pn -> enter = f;
}

void panel_mouse_leave(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, void *userdata))
{
	pn -> leave = f;
}

void panel_get_pos(struct Panel *pn, int *x, int *y)
{
	*x = pn -> px;
	*y = pn -> py;
}

void panel_get_abs_pos(struct Panel *pn, int *x, int *y)
{
	*x = pn -> _area -> _x;
	*y = pn -> _area -> _y;
}

void panel_set_pos(struct Panel *pn, int x, int y)
{
	int dx, dy;
	dx = x - pn -> px;
	dy = y - pn -> py;
	
	area_move(pn -> _area, dx, dy);
	
	pn -> px = x;
	pn -> py = y;
}

void panel_get_size(struct Panel *pn, int *w, int *h)
{
	*w = pn -> _area -> _width;
	*h = pn -> _area -> _height;
}

void panel_set_size(struct Panel *pn, int w, int h)
{
	pn -> _area -> _width = w;
	pn -> _area -> _height = h;
}


void panel_set_enable(struct Panel *pn, int en)
{
	pn -> _area -> enable = en;
}
void panel_set_visual(struct Panel *pn, int vi)
{
	pn -> _area -> visual = vi;
}

int panel_get_enable(struct Panel *pn)
{
	return pn -> _area -> enable;
}
int panel_get_visual(struct Panel *pn)
{
	return pn -> _area -> visual;
}
void panel_set_userdata(struct Panel *pn, void *data)
{
	pn -> userdata = data;
}

